package main

import (
	"fmt"
	"time"
)

// 抽象产品接口
// 支付
type PaymentService interface {
	ProcessPayment(amount float64, currency string) error
	GetPaymentMethod() string
	ValidatePayment() bool
}

// 物流
type LogisticsService interface {
	CalculateShipping(weight float64, distance float64) float64
	GetDeliveryTime(distance float64) time.Duration
	GetServiceName() string
}

// 抽象工厂接口
type ECommerceServiceFactory interface {
	CreatePaymentService(config map[string]string) PaymentService
	CreateLogisticsService(config map[string]string) LogisticsService
	GetFactoryType() string
}

// 国内服务产品族
type DomesticPaymentService struct {
	BankAccount string
	Currency    string
}

func (d *DomesticPaymentService) ProcessPayment(amount float64, currency string) error {
	if currency != "CNY" {
		return fmt.Errorf("国内支付服务只支持人民币")
	}
	fmt.Printf("国内支付：使用银行账户 %s 支付 %.2f %s\n", d.BankAccount, amount, currency)
	return nil
}

func (d *DomesticPaymentService) GetPaymentMethod() string {
	return "国内银行转账"
}

func (d *DomesticPaymentService) ValidatePayment() bool {
	return len(d.BankAccount) > 0
}

type DomesticLogisticsService struct {
	CompanyName string
	ServiceType string
}

func (d *DomesticLogisticsService) CalculateShipping(weight float64, distance float64) float64 {
	baseRate := 5.0
	weightRate := weight * 0.5
	distanceRate := distance * 0.01
	return baseRate + weightRate + distanceRate
}

func (d *DomesticLogisticsService) GetDeliveryTime(distance float64) time.Duration {
	if distance < 100 {
		return 24 * time.Hour
	} else if distance < 500 {
		return 48 * time.Hour
	}
	return 72 * time.Hour
}

func (d *DomesticLogisticsService) GetServiceName() string {
	return fmt.Sprintf("%s - %s", d.CompanyName, d.ServiceType)
}

// 国际服务产品族
type InternationalPaymentService struct {
	SwiftCode string
	Currency  string
}

func (i *InternationalPaymentService) ProcessPayment(amount float64, currency string) error {
	fmt.Printf("国际支付：通过SWIFT %s 支付 %.2f %s\n", i.SwiftCode, amount, currency)
	return nil
}

func (i *InternationalPaymentService) GetPaymentMethod() string {
	return "国际电汇"
}

func (i *InternationalPaymentService) ValidatePayment() bool {
	return len(i.SwiftCode) > 0
}

type InternationalLogisticsService struct {
	Carrier     string
	ServiceType string
}

func (i *InternationalLogisticsService) CalculateShipping(weight float64, distance float64) float64 {
	baseRate := 20.0
	weightRate := weight * 2.0
	distanceRate := distance * 0.05
	return baseRate + weightRate + distanceRate
}

func (i *InternationalLogisticsService) GetDeliveryTime(distance float64) time.Duration {
	if distance < 1000 {
		return 3 * 24 * time.Hour
	} else if distance < 5000 {
		return 7 * 24 * time.Hour
	}
	return 14 * 24 * time.Hour
}

func (i *InternationalLogisticsService) GetServiceName() string {
	return fmt.Sprintf("%s 国际快递 - %s", i.Carrier, i.ServiceType)
}

// 具体工厂实现
type DomesticServiceFactory struct{}

func (d *DomesticServiceFactory) CreatePaymentService(config map[string]string) PaymentService {
	return &DomesticPaymentService{
		BankAccount: config["bank_account"],
		Currency:    "CNY",
	}
}

func (d *DomesticServiceFactory) CreateLogisticsService(config map[string]string) LogisticsService {
	return &DomesticLogisticsService{
		CompanyName: config["company_name"],
		ServiceType: config["service_type"],
	}
}

func (d *DomesticServiceFactory) GetFactoryType() string {
	return "国内服务工厂"
}

type InternationalServiceFactory struct{}

func (i *InternationalServiceFactory) CreatePaymentService(config map[string]string) PaymentService {
	return &InternationalPaymentService{
		SwiftCode: config["swift_code"],
		Currency:  config["currency"],
	}
}

func (i *InternationalServiceFactory) CreateLogisticsService(config map[string]string) LogisticsService {
	return &InternationalLogisticsService{
		Carrier:     config["carrier"],
		ServiceType: config["service_type"],
	}
}

func (i *InternationalServiceFactory) GetFactoryType() string {
	return "国际服务工厂"
}

// 使用演示
func main() {
	fmt.Println("=== 电商服务工厂演示 ===")

	factories := map[string]ECommerceServiceFactory{
		"domestic":      &DomesticServiceFactory{},
		"international": &InternationalServiceFactory{},
	}

	for _, factory := range factories {
		fmt.Printf("=== %s ===\n", factory.GetFactoryType())

		// 创建支付服务
		paymentConfig := map[string]string{
			"bank_account": "1234567890",
			"swift_code":   "ABCDUS33",
			"currency":     "USD",
		}
		payment := factory.CreatePaymentService(paymentConfig)
		payment.ProcessPayment(100.0, "USD")

		// 创建物流服务
		logisticsConfig := map[string]string{
			"company_name": "顺丰快递",
			"carrier":      "DHL",
			"service_type": "标准",
		}
		logistics := factory.CreateLogisticsService(logisticsConfig)
		cost := logistics.CalculateShipping(2.5, 500.0)
		deliveryTime := logistics.GetDeliveryTime(500.0)

		fmt.Printf("物流服务: %s\n", logistics.GetServiceName())
		fmt.Printf("运费: $%.2f, 预计送达: %v\n", cost, deliveryTime)
		fmt.Println()
	}
}
